<template>
  <div class="ai-inner-chat">
    <!-- 建议问题卡片 -->
    <div v-if="!messages.length && suggestedQuestions && suggestedQuestions.length" class="question-cards">
      <slot name="question-cards" :questions="suggestedQuestions" :ask="askSuggestedQuestion">
        <div class="question-grid">
          <div
            v-for="(q, index) in suggestedQuestions"
            :key="index"
            class="question-card"
            @click="askSuggestedQuestion(q.question)"
          >
            <i :class="q.icon" :style="{ color: q.color }" />
            <div class="question-title">{{ q.title }}</div>
            <div class="question-text">{{ q.question }}</div>
          </div>
        </div>
      </slot>
    </div>

    <!-- 选中文本提示 -->
    <div v-if="selectedTextPreview" class="selected-text-hint">
      <div class="hint-header">
        <i class="el-icon-document" style="color: #1EB7E6;" />
        <span class="hint-title">当前选中的内容:</span>
        <el-button
          type="text"
          size="mini"
          icon="el-icon-close"
          class="clear-btn"
          @click="clearSelectedText"
        />
      </div>
      <div class="hint-content">
        {{ selectedTextPreview }}
      </div>
    </div>

    <!-- 消息列表 -->
    <div ref="messageList" class="message-list">
      <div
        v-for="(msg, index) in messages"
        :key="index"
        :class="['message-item', msg.role === 'user' ? 'user-message' : 'assistant-message']"
      >
        <div class="message-wrapper">
          <div class="message-avatar">
            <i v-if="msg.role === 'user'" class="el-icon-user-solid" />
            <svg v-else width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
              <defs>
                <linearGradient id="aiGrad" x1="2" y1="2" x2="22" y2="22" gradientUnits="userSpaceOnUse">
                  <stop offset="0%" stop-color="#3B82F6" />
                  <stop offset="50%" stop-color="#8B5CF6" />
                  <stop offset="100%" stop-color="#EC4899" />
                </linearGradient>
                <filter id="aiGlow" x="-20%" y="-20%" width="140%" height="140%">
                  <feGaussianBlur stdDeviation="1" result="blur" />
                  <feComposite in="SourceGraphic" in2="blur" operator="over" />
                </filter>
              </defs>
              <path d="M12 2L14.5 9.5L22 12L14.5 14.5L12 22L9.5 14.5L2 12L9.5 9.5L12 2Z" fill="url(#aiGrad)" filter="url(#aiGlow)" />
              <path d="M12 6L13 9L16 10L13 11L12 14L11 11L8 10L11 9L12 6Z" fill="white" fill-opacity="0.4" />
            </svg>
          </div>
          <div class="message-content">
            <div v-if="msg.role === 'assistant'">
              <!-- 如果有解析的JSON数据,直接显示生成的HTML内容 -->
              <div v-if="msg.parsedData && msg.parsedData.content" class="generated-content">
                <div class="content-label">AI生成的内容:</div>
                <div class="content-preview" v-html="msg.parsedData.content" />
                <div class="message-actions">
                  <el-button
                    type="primary"
                    size="mini"
                    icon="el-icon-document-copy"
                    style="background-color: #1EB7E6; border-color: #1EB7E6;"
                    @click="copyAsRichText(msg.parsedData.content)"
                  >
                    复制富文本
                  </el-button>
                  <el-button
                    type="text"
                    size="mini"
                    icon="el-icon-code"
                    @click="copyContent(msg.parsedData.content)"
                  >
                    复制源码
                  </el-button>
                  <el-button
                    type="text"
                    size="mini"
                    icon="el-icon-view"
                    @click="showSourceCode(msg.parsedData.content)"
                  >
                    查看源码
                  </el-button>
                </div>
              </div>
              <!-- 否则显示普通Markdown内容 -->
              <div v-else class="markdown-content">
                <div ref="markdownContainer" @DOMNodeInserted="addCodeBlockButtons" v-html="renderMarkdown(msg.content)" />
              </div>
            </div>
            <div v-else>{{ msg.content }}</div>
          </div>
        </div>
      </div>

      <!-- 加载中指示器 -->
      <div v-if="isLoading" class="message-item assistant-message">
        <div class="message-wrapper">
          <div class="message-avatar">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
              <defs>
                <linearGradient id="aiGradLoad" x1="2" y1="2" x2="22" y2="22" gradientUnits="userSpaceOnUse">
                  <stop offset="0%" stop-color="#3B82F6" />
                  <stop offset="50%" stop-color="#8B5CF6" />
                  <stop offset="100%" stop-color="#EC4899" />
                </linearGradient>
                <filter id="aiGlowLoad" x="-20%" y="-20%" width="140%" height="140%">
                  <feGaussianBlur stdDeviation="1" result="blur" />
                  <feComposite in="SourceGraphic" in2="blur" operator="over" />
                </filter>
              </defs>
              <path d="M12 2L14.5 9.5L22 12L14.5 14.5L12 22L9.5 14.5L2 12L9.5 9.5L12 2Z" fill="url(#aiGradLoad)" filter="url(#aiGlowLoad)" />
              <path d="M12 6L13 9L16 10L13 11L12 14L11 11L8 10L11 9L12 6Z" fill="white" fill-opacity="0.4" />
            </svg>
          </div>
          <div class="message-content">
            <div class="loading-dots">
              <span>.</span><span>.</span><span>.</span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 快捷命令区域 -->
    <div v-if="quickCommands.length > 0" class="quick-commands">
      <el-tag
        v-for="(cmd, index) in quickCommands"
        :key="index"
        class="command-tag"
        size="mini"
        :type="cmd.type || 'info'"
        @click="useQuickCommand(cmd)"
      >
        <i v-if="cmd.icon" :class="cmd.icon" />
        {{ cmd.label }}
      </el-tag>
    </div>

    <!-- 输入区域 -->
    <div class="input-area">
      <el-input
        v-model="userInput"
        type="textarea"
        :rows="3"
        :placeholder="placeholder"
        :disabled="isLoading"
        @keydown.enter.ctrl="handleSend"
      />
      <div class="input-actions">
        <span class="input-tip">Ctrl+Enter 发送</span>
        <el-button
          type="primary"
          :loading="isLoading"
          :disabled="!userInput.trim()"
          @click="handleSend"
        >
          {{ isLoading ? '生成中...' : '发送' }}
        </el-button>
      </div>
    </div>
  </div>
</template>

<script>
import { marked } from 'marked'
import { getToken } from '@/utils/auth'

export default {
  name: 'AIInnerChat',
  props: {
    // API 配置
    apiUrl: {
      type: String,
      required: true
    },
    handlerName: {
      type: String,
      required: true
    },
    contextData: {
      type: Object,
      default: () => ({})
    },
    // AI 引擎
    engine: {
      type: String,
      default: 'claude-sonnet-4.5'
    },
    // UI 配置
    placeholder: {
      type: String,
      default: '请输入您的问题...'
    },
    suggestedQuestions: {
      type: Array,
      default: () => []
    },
    // 自动解析JSON
    autoParseJson: {
      type: Boolean,
      default: true // 默认开启自动解析
    },
    // 显示填充按钮
    showFillButton: {
      type: Boolean,
      default: true
    },
    // 快捷命令列表
    quickCommands: {
      type: Array,
      default: () => []
    },
    // 初始欢迎消息
    welcomeMessage: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      userInput: '',
      messages: [],
      isLoading: false,
      abortController: null,
      parsedData: null
    }
  },
  mounted() {
    // 如果有欢迎消息且消息列表为空,显示欢迎消息
    if (this.welcomeMessage && this.messages.length === 0) {
      this.messages.push({
        role: 'assistant',
        content: this.welcomeMessage,
        timestamp: new Date()
      })
      this.$nextTick(() => this.scrollToBottom())
    }
  },
  computed: {
    headers() {
      return {
        'Authorization': getToken(),
        'PTOKEN': this.$store.getters.projectId,
        'Content-Type': 'application/json'
      }
    },
    // 选中文本的预览(前30个字符)
    selectedTextPreview() {
      if (!this.contextData || !this.contextData.selected_text) {
        return ''
      }

      const text = this.contextData.selected_text.trim()
      if (!text) {
        return ''
      }

      // 显示前30个字符,如果超过则添加省略号
      if (text.length > 30) {
        return text.substring(0, 30) + '...'
      }
      return text
    }
  },
  watch: {
    messages: {
      handler() {
        this.$nextTick(() => {
          this.scrollToBottom()
          this.addCodeBlockButtons() // 为新的代码块添加按钮
        })
      },
      deep: true
    }
  },
  methods: {
    // 发送消息
    async handleSend() {
      if (!this.userInput.trim() || this.isLoading) return

      const userMessage = this.userInput.trim()
      this.userInput = ''

      // 添加用户消息
      this.messages.push({
        role: 'user',
        content: userMessage,
        timestamp: new Date()
      })

      this.$nextTick(() => this.scrollToBottom())

      // 开始流式请求
      this.isLoading = true
      this.abortController = new AbortController()

      try {
        const response = await fetch(`${process.env.VUE_APP_BASE_API}${this.apiUrl}`, {
          method: 'POST',
          headers: this.headers,
          body: JSON.stringify({
            handler_name: this.handlerName,
            user_message: userMessage,
            engine: this.engine,
            context_data: this.contextData,
            chat_history: this.messages // 包含所有历史消息
          }),
          signal: this.abortController.signal
        })

        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`)
        }

        const reader = response.body.getReader()
        const decoder = new TextDecoder()
        let fullText = ''
        let buffer = ''
        let done = false
        let assistantIndex = -1 // 延迟创建assistant消息

        while (!done) {
          const result = await reader.read()
          done = result.done

          if (!done) {
            const chunk = decoder.decode(result.value, { stream: true })
            buffer += chunk

            // 解析SSE格式：data: {"type": "text", "content": "..."}
            const lines = buffer.split('\n')
            buffer = lines.pop() || '' // 保留最后一个不完整的行

            for (const line of lines) {
              if (line.startsWith('data: ')) {
                const data = line.substring(6).trim()
                if (data === '[DONE]') {
                  continue
                }
                try {
                  const parsed = JSON.parse(data)
                  if (parsed.type === 'text' && parsed.content) {
                    fullText += parsed.content

                    // 第一次收到内容时创建assistant消息
                    if (assistantIndex === -1) {
                      assistantIndex = this.messages.length
                      this.messages.push({
                        role: 'assistant',
                        content: '',
                        timestamp: new Date()
                      })
                    }
                  } else if (parsed.type === 'error') {
                    // 处理错误
                    this.$message.error('AI错误: ' + parsed.content)
                    if (assistantIndex !== -1) {
                      this.$set(this.messages[assistantIndex], 'content', `[错误: ${parsed.content}]`)
                    }
                    return
                  }
                } catch (e) {
                  console.debug('解析SSE数据失败:', data, e)
                }
              } else if (line.trim()) {
                // 兼容模式:如果不是SSE格式,直接累加纯文本
                fullText += line

                // 第一次收到内容时创建assistant消息
                if (assistantIndex === -1) {
                  assistantIndex = this.messages.length
                  this.messages.push({
                    role: 'assistant',
                    content: '',
                    timestamp: new Date()
                  })
                }
              }
            }

            // 更新消息内容
            if (assistantIndex !== -1) {
              this.$set(this.messages[assistantIndex], 'content', fullText)
              this.$nextTick(() => this.scrollToBottom())
            }
          }
        }

        // 流式响应完成，触发回调
        this.$emit('message-completed', {
          role: 'assistant',
          content: fullText
        })

        // 如果开启自动解析JSON
        if (this.autoParseJson) {
          const parsedData = this.tryParseJson(fullText)
          if (parsedData) {
            // 将解析后的数据保存到消息对象中
            this.$set(this.messages[assistantIndex], 'parsedData', parsedData)

            // 不再自动替换,所有生成的内容都只在对话框显示
            // 用户可以通过"复制"按钮手动使用
          }
        }
      } catch (error) {
        if (error.name === 'AbortError') {
          this.$message.info('已取消请求')
        } else {
          console.error('AI对话错误:', error)
          this.$message.error('AI对话失败: ' + error.message)
        }
        // 添加错误消息
        this.messages.push({
          role: 'assistant',
          content: `[错误: ${error.message || '请求失败'}]`,
          timestamp: new Date()
        })
      } finally {
        this.isLoading = false
        this.abortController = null
      }
    },

    // 发送消息（支持显示文本和实际发送文本不同）
    async handleSendWithCommand(commandText, displayText = null) {
      if (this.isLoading) return

      const actualMessage = commandText // 发送给后端的实际命令
      const showMessage = displayText || commandText // 显示给用户的文本

      // 添加用户消息（显示友好文本）
      this.messages.push({
        role: 'user',
        content: showMessage,
        timestamp: new Date()
      })

      this.$nextTick(() => this.scrollToBottom())

      // 开始流式请求
      this.isLoading = true
      this.abortController = new AbortController()

      try {
        const response = await fetch(`${process.env.VUE_APP_BASE_API}${this.apiUrl}`, {
          method: 'POST',
          headers: this.headers,
          body: JSON.stringify({
            handler_name: this.handlerName,
            user_message: actualMessage, // 发送实际命令
            engine: this.engine,
            context_data: this.contextData,
            chat_history: this.messages
          }),
          signal: this.abortController.signal
        })

        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`)
        }

        const reader = response.body.getReader()
        const decoder = new TextDecoder()
        let fullText = ''
        let buffer = ''
        let done = false
        let assistantIndex = -1

        while (!done) {
          const result = await reader.read()
          done = result.done

          if (!done) {
            const chunk = decoder.decode(result.value, { stream: true })
            buffer += chunk

            const lines = buffer.split('\n')
            buffer = lines.pop() || ''

            for (const line of lines) {
              if (line.startsWith('data: ')) {
                const data = line.substring(6).trim()
                if (data === '[DONE]') continue
                try {
                  const parsed = JSON.parse(data)
                  if (parsed.type === 'text' && parsed.content) {
                    fullText += parsed.content
                    if (assistantIndex === -1) {
                      assistantIndex = this.messages.length
                      this.messages.push({ role: 'assistant', content: '', timestamp: new Date() })
                    }
                  } else if (parsed.type === 'error') {
                    this.$message.error('AI错误: ' + parsed.content)
                    return
                  }
                } catch (e) {
                  console.debug('解析SSE数据失败:', data, e)
                }
              }
            }

            if (assistantIndex !== -1) {
              this.$set(this.messages[assistantIndex], 'content', fullText)
              this.$nextTick(() => this.scrollToBottom())
            }
          }
        }

        this.$emit('message-completed', { role: 'assistant', content: fullText })
      } catch (error) {
        if (error.name !== 'AbortError') {
          console.error('AI对话错误:', error)
          this.$message.error('AI对话失败: ' + error.message)
        }
        this.messages.push({ role: 'assistant', content: `[错误: ${error.message || '请求失败'}]`, timestamp: new Date() })
      } finally {
        this.isLoading = false
        this.abortController = null
      }
    },

    // 点击建议问题
    askSuggestedQuestion(question) {
      this.userInput = question
      this.handleSend()
    },

    // 使用快捷命令
    useQuickCommand(cmd) {
      // 支持对象格式 {text, displayText, fillOnly} 或纯字符串
      const commandText = typeof cmd === 'string' ? cmd : cmd.text
      const displayText = typeof cmd === 'string' ? cmd : (cmd.displayText || cmd.text)
      const fillOnly = typeof cmd === 'object' && cmd.fillOnly

      if (fillOnly) {
        // 只填充输入框，不自动发送
        this.userInput = commandText
      } else {
        // 发送时用实际命令，但显示友好文本
        this.handleSendWithCommand(commandText, displayText)
      }
    },

    // 公开方法：发送消息（供父组件调用）
    sendMessage(message) {
      this.userInput = message
      this.handleSend()
    },

    // 取消请求
    cancelRequest() {
      if (this.abortController) {
        this.abortController.abort()
        this.abortController = null
      }
    },

    // 尝试解析JSON
    tryParseJson(text) {
      try {
        // 尝试提取JSON代码块 (非贪婪模式)
        const jsonMatch = text.match(/```json\n([\s\S]*?)\n```/) ||
                         text.match(/```\n([\s\S]*?)\n```/)

        if (jsonMatch) {
          const jsonStr = jsonMatch[1].trim()
          console.log('提取的JSON字符串:', jsonStr.substring(0, 200) + '...')
          const jsonData = JSON.parse(jsonStr)
          console.log('解析成功的JSON:', jsonData)

          // 验证content字段
          if (jsonData.content && jsonData.content.length < 50) {
            console.warn('警告: content字段太短,可能被截断:', jsonData.content)
          }

          this.parsedData = jsonData
          this.$emit('json-parsed', jsonData)
          return jsonData
        }

        // 尝试直接解析整个文本
        const jsonData = JSON.parse(text)
        console.log('直接解析成功的JSON:', jsonData)
        this.parsedData = jsonData
        this.$emit('json-parsed', jsonData)
        return jsonData
      } catch (e) {
        // 不是有效的JSON，忽略
        console.debug('无法解析JSON:', e.message, '文本长度:', text.length)
        return null
      }
    },

    // 复制富文本格式到剪贴板(保留格式,不是HTML源码)
    async copyAsRichText(htmlContent) {
      try {
        // 创建临时DOM元素来渲染HTML
        const tempDiv = document.createElement('div')
        tempDiv.innerHTML = htmlContent
        tempDiv.style.position = 'fixed'
        tempDiv.style.left = '-9999px'
        document.body.appendChild(tempDiv)

        // 选中内容
        const range = document.createRange()
        range.selectNodeContents(tempDiv)
        const selection = window.getSelection()
        selection.removeAllRanges()
        selection.addRange(range)

        // 使用现代 Clipboard API 复制富文本
        if (navigator.clipboard && window.ClipboardItem) {
          try {
            // 获取选中内容的HTML
            const htmlBlob = new Blob([htmlContent], { type: 'text/html' })
            const textBlob = new Blob([tempDiv.innerText], { type: 'text/plain' })

            // eslint-disable-next-line no-undef
            const clipboardItem = new ClipboardItem({
              'text/html': htmlBlob,
              'text/plain': textBlob
            })

            await navigator.clipboard.write([clipboardItem])
            this.$message.success('富文本已复制,可直接粘贴到编辑器保留格式')
          } catch (clipboardErr) {
            // 降级到 execCommand
            document.execCommand('copy')
            this.$message.success('富文本已复制')
          }
        } else {
          // 降级方案: 使用 execCommand
          document.execCommand('copy')
          this.$message.success('富文本已复制')
        }

        // 清理
        selection.removeAllRanges()
        document.body.removeChild(tempDiv)
      } catch (err) {
        console.error('复制富文本失败:', err)
        this.$message.error('复制失败: ' + err.message)
      }
    },

    // 复制Markdown渲染后的富文本
    async copyMarkdownAsRichText(markdownContent) {
      try {
        // 先将Markdown转换为HTML
        const htmlContent = this.renderMarkdown(markdownContent)

        // 创建临时DOM元素来渲染HTML
        const tempDiv = document.createElement('div')
        tempDiv.innerHTML = htmlContent
        tempDiv.style.position = 'fixed'
        tempDiv.style.left = '-9999px'
        document.body.appendChild(tempDiv)

        // 选中内容
        const range = document.createRange()
        range.selectNodeContents(tempDiv)
        const selection = window.getSelection()
        selection.removeAllRanges()
        selection.addRange(range)

        // 使用现代 Clipboard API 复制富文本
        if (navigator.clipboard && window.ClipboardItem) {
          try {
            const htmlBlob = new Blob([htmlContent], { type: 'text/html' })
            const textBlob = new Blob([tempDiv.innerText], { type: 'text/plain' })

            // eslint-disable-next-line no-undef
            const clipboardItem = new ClipboardItem({
              'text/html': htmlBlob,
              'text/plain': textBlob
            })

            await navigator.clipboard.write([clipboardItem])
            this.$message.success('内容已复制,可直接粘贴到编辑器')
          } catch (clipboardErr) {
            document.execCommand('copy')
            this.$message.success('内容已复制')
          }
        } else {
          document.execCommand('copy')
          this.$message.success('内容已复制')
        }

        // 清理
        selection.removeAllRanges()
        document.body.removeChild(tempDiv)
      } catch (err) {
        console.error('复制失败:', err)
        this.$message.error('复制失败: ' + err.message)
      }
    },

    // 复制纯文本(去除Markdown格式)
    async copyPlainText(markdownContent) {
      try {
        // 将Markdown转换为HTML再提取纯文本
        const htmlContent = this.renderMarkdown(markdownContent)
        const tempDiv = document.createElement('div')
        tempDiv.innerHTML = htmlContent
        const plainText = tempDiv.innerText

        await navigator.clipboard.writeText(plainText)
        this.$message.success('纯文本已复制到剪贴板')
      } catch (err) {
        // 降级方案
        const textarea = document.createElement('textarea')
        textarea.value = markdownContent
        textarea.style.position = 'fixed'
        textarea.style.opacity = '0'
        document.body.appendChild(textarea)
        textarea.select()
        document.execCommand('copy')
        document.body.removeChild(textarea)
        this.$message.success('纯文本已复制到剪贴板')
      }
    },

    // 复制HTML源码到剪贴板
    async copyContent(htmlContent) {
      try {
        await navigator.clipboard.writeText(htmlContent)
        this.$message.success('HTML源码已复制到剪贴板')
      } catch (err) {
        // 降级方案:创建临时textarea
        const textarea = document.createElement('textarea')
        textarea.value = htmlContent
        textarea.style.position = 'fixed'
        textarea.style.opacity = '0'
        document.body.appendChild(textarea)
        textarea.select()
        document.execCommand('copy')
        document.body.removeChild(textarea)
        this.$message.success('HTML源码已复制到剪贴板')
      }
    },

    // 显示HTML源码
    showSourceCode(htmlContent) {
      this.$alert(
        `<pre style="max-height: 400px; overflow-y: auto; background: #f5f5f5; padding: 10px; border-radius: 4px;"><code>${this.escapeHtml(htmlContent)}</code></pre>`,
        'HTML 源码',
        {
          dangerouslyUseHTMLString: true,
          confirmButtonText: '关闭'
        }
      )
    },

    // 转义HTML用于显示
    escapeHtml(html) {
      return html
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;')
    },

    // 渲染 Markdown
    renderMarkdown(content) {
      if (!content) return ''
      try {
        return marked(content)
      } catch (e) {
        return content
      }
    },

    // 滚动到底部
    scrollToBottom() {
      if (this.$refs.messageList) {
        this.$nextTick(() => {
          this.$refs.messageList.scrollTop = this.$refs.messageList.scrollHeight
        })
      }
    },

    // 清空对话
    clearMessages() {
      this.messages = []
      this.parsedData = null
    },

    // 清除选中文本提示
    clearSelectedText() {
      // 触发父组件清除选区
      this.$emit('clear-selection')
      this.$message.info('已清除选中文本')
    },

    // 为代码块添加复制按钮
    addCodeBlockButtons() {
      this.$nextTick(() => {
        // 查找所有 pre > code 元素
        const codeBlocks = this.$el.querySelectorAll('.markdown-content pre')

        codeBlocks.forEach((pre) => {
          // 避免重复添加按钮
          if (pre.querySelector('.code-block-actions')) {
            return
          }

          const code = pre.querySelector('code')
          if (!code) return

          // 创建按钮容器
          const actionsDiv = document.createElement('div')
          actionsDiv.className = 'code-block-actions'

          // 复制富文本按钮
          const copyRichBtn = document.createElement('button')
          copyRichBtn.className = 'code-action-btn primary'
          copyRichBtn.innerHTML = '<i class="el-icon-document-copy"></i> 复制富文本'
          copyRichBtn.onclick = () => {
            const htmlContent = code.innerHTML
            this.copyCodeAsRichText(htmlContent)
          }

          // 复制纯文本按钮
          const copyTextBtn = document.createElement('button')
          copyTextBtn.className = 'code-action-btn'
          copyTextBtn.innerHTML = '<i class="el-icon-chat-dot-square"></i> 复制纯文本'
          copyTextBtn.onclick = () => {
            const plainText = code.textContent
            this.copyCodeAsPlainText(plainText)
          }

          actionsDiv.appendChild(copyRichBtn)
          actionsDiv.appendChild(copyTextBtn)

          // 将按钮容器添加到 pre 标签内部顶部
          pre.style.position = 'relative'
          pre.insertBefore(actionsDiv, pre.firstChild)
        })
      })
    },

    // 复制代码块的富文本
    async copyCodeAsRichText(htmlContent) {
      try {
        // 创建一个临时的、带样式的容器来渲染内容
        const tempDiv = document.createElement('div')
        tempDiv.innerHTML = htmlContent

        // 应用样式使其看起来像实际渲染的内容
        tempDiv.style.position = 'fixed'
        tempDiv.style.left = '-9999px'
        tempDiv.style.fontFamily = 'Consolas, Monaco, "Courier New", monospace'
        tempDiv.style.fontSize = '14px'
        tempDiv.style.lineHeight = '1.6'
        tempDiv.style.whiteSpace = 'pre-wrap'
        tempDiv.style.wordBreak = 'break-word'
        document.body.appendChild(tempDiv)

        // 提取纯文本内容
        const plainText = tempDiv.textContent || tempDiv.innerText

        // 创建富文本HTML，保留格式但去掉语法高亮标签
        // 将内容包装在段落标签中，保持换行和格式
        const formattedHtml = `<div style="font-family: Consolas, Monaco, 'Courier New', monospace; font-size: 14px; line-height: 1.6; white-space: pre-wrap; word-break: break-word;">${plainText}</div>`

        // 选中内容用于 execCommand 降级方案
        const range = document.createRange()
        range.selectNodeContents(tempDiv)
        const selection = window.getSelection()
        selection.removeAllRanges()
        selection.addRange(range)

        // 尝试使用现代 Clipboard API
        if (navigator.clipboard && window.ClipboardItem) {
          try {
            const htmlBlob = new Blob([formattedHtml], { type: 'text/html' })
            const textBlob = new Blob([plainText], { type: 'text/plain' })

            // eslint-disable-next-line no-undef
            const clipboardItem = new ClipboardItem({
              'text/html': htmlBlob,
              'text/plain': textBlob
            })

            await navigator.clipboard.write([clipboardItem])
            this.$message.success('富文本已复制,可直接粘贴到编辑器')
          } catch (err) {
            console.warn('Clipboard API失败，使用execCommand:', err)
            // 降级到 execCommand
            document.execCommand('copy')
            this.$message.success('富文本已复制')
          }
        } else {
          document.execCommand('copy')
          this.$message.success('富文本已复制')
        }

        // 清理
        selection.removeAllRanges()
        document.body.removeChild(tempDiv)
      } catch (err) {
        console.error('复制富文本失败:', err)
        this.$message.error('复制失败: ' + err.message)
      }
    },

    // 复制代码块的纯文本
    async copyCodeAsPlainText(plainText) {
      try {
        await navigator.clipboard.writeText(plainText)
        this.$message.success('纯文本已复制')
      } catch (err) {
        // 降级方案
        const textarea = document.createElement('textarea')
        textarea.value = plainText
        textarea.style.position = 'fixed'
        textarea.style.opacity = '0'
        document.body.appendChild(textarea)
        textarea.select()
        document.execCommand('copy')
        document.body.removeChild(textarea)
        this.$message.success('纯文本已复制')
      }
    }
  },
  beforeDestroy() {
    this.cancelRequest()
  }
}
</script>

<style lang="scss" scoped>
.ai-inner-chat {
  display: flex;
  flex-direction: column;
  height: 100%;
  background-color: #f5f7fa;

  // 建议问题卡片
  .question-cards {
    padding: 20px;
    overflow-y: auto;

    .question-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
      gap: 15px;

      .question-card {
        background: white;
        border-radius: 8px;
        padding: 15px;
        cursor: pointer;
        transition: all 0.3s;
        border: 1px solid #e4e7ed;

        &:hover {
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
          transform: translateY(-2px);
        }

        i {
          font-size: 24px;
          margin-bottom: 8px;
        }

        .question-title {
          font-weight: 600;
          margin-bottom: 5px;
          color: #303133;
        }

        .question-text {
          font-size: 12px;
          color: #909399;
          line-height: 1.4;
        }
      }
    }
  }

  // 消息列表
  .message-list {
    flex: 1;
    overflow-y: auto;
    padding: 20px;

    .message-item {
      margin-bottom: 20px;

      .message-wrapper {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
      }

      .message-avatar {
        width: 32px;
        height: 32px;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        flex-shrink: 0;
        margin-bottom: 8px;

        i {
          font-size: 16px;
        }
      }

      .message-content {
        max-width: 100%;
        padding: 12px 8px;
        border-radius: 8px;
        line-height: 1.6;
        word-wrap: break-word;

        ::v-deep {
          p {
            margin: 0 0 10px 0;
            &:last-child {
              margin-bottom: 0;
            }
          }

          code {
            background-color: #f4f4f5;
            padding: 2px 6px;
            border-radius: 3px;
            font-family: 'Courier New', monospace;
          }

          pre {
            background-color: #f4f4f5;
            padding: 12px;
            border-radius: 4px;
            overflow-x: auto;
            margin: 10px 0;

            code {
              background: none;
              padding: 0;
            }
          }

          ul, ol {
            margin: 10px 0;
            padding-left: 20px;
          }

          blockquote {
            border-left: 4px solid #dcdfe6;
            padding-left: 12px;
            margin: 10px 0;
            color: #606266;
          }

          img {
            max-width: 100%;
            height: auto;
            border-radius: 8px;
            margin: 10px 0;
            display: block;
          }
        }
      }

      &.user-message {
        .message-avatar {
          background-color: #409eff;
          color: white;
        }

        .message-content {
          background-color: #409eff;
          color: white;
        }
      }

      &.assistant-message {
        .message-avatar {
          background-color: transparent;
        }

        .message-content {
          background-color: white;
          color: #303133;
          border: 1px solid #e4e7ed;
        }
      }
    }

    // 生成的内容样式
    .generated-content {
      .content-label {
        font-size: 12px;
        color: #909399;
        margin-bottom: 8px;
        font-weight: 600;
      }

      .content-preview {
        background: #f9fafb;
        border: 1px solid #e4e7ed;
        border-radius: 4px;
        padding: 12px;
        margin-bottom: 12px;
        max-height: 400px;
        overflow-y: auto;

        // 保持生成内容的样式
        ::v-deep {
          h1, h2, h3, h4, h5, h6 {
            margin: 10px 0;
            color: #303133;
          }

          p {
            margin: 8px 0;
            line-height: 1.6;
          }

          ul, ol {
            margin: 8px 0;
            padding-left: 24px;
          }

          img {
            max-width: 100%;
            height: auto;
            margin: 10px 0;
          }

          a {
            color: #409eff;
            text-decoration: none;
            &:hover {
              text-decoration: underline;
            }
          }
        }
      }
    }

    // Markdown内容样式
    .markdown-content {
      ::v-deep {
        h1, h2, h3, h4, h5, h6 {
          margin: 10px 0;
          color: #303133;
        }

        p {
          margin: 8px 0;
          line-height: 1.6;
        }

        ul, ol {
          margin: 8px 0;
          padding-left: 24px;
        }

        strong {
          font-weight: 600;
          color: #303133;
        }

        code {
          background-color: #f4f4f5;
          padding: 2px 6px;
          border-radius: 3px;
          font-family: 'Courier New', monospace;
        }

        pre {
          background-color: #f4f4f5;
          padding: 45px 12px 12px 12px; // 顶部留空间给按钮
          border-radius: 4px;
          overflow-x: auto;
          position: relative;
          max-width: 100%;
          width: 100%;
          box-sizing: border-box;
          word-wrap: break-word;
          white-space: pre-wrap;

          code {
            background: none;
            padding: 0;
            display: block;
            max-width: 100%;
            word-wrap: break-word;
            white-space: pre-wrap;
            overflow-wrap: break-word;
          }

          // 代码块按钮容器
          .code-block-actions {
            position: absolute;
            top: 8px;
            left: 8px;
            display: flex;
            gap: 6px;
            z-index: 10;
          }

          // 代码块按钮样式
          .code-action-btn {
            padding: 4px 10px;
            font-size: 12px;
            border: 1px solid #d0d0d0;
            background-color: white;
            color: #606266;
            border-radius: 3px;
            cursor: pointer;
            transition: all 0.3s;
            display: flex;
            align-items: center;
            gap: 4px;

            i {
              font-size: 12px;
            }

            &:hover {
              background-color: #f5f7fa;
              border-color: #c0c4cc;
            }

            &.primary {
              background-color: #1EB7E6;
              border-color: #1EB7E6;
              color: white;

              &:hover {
                background-color: #17a2ce;
                border-color: #17a2ce;
              }
            }
          }
        }
      }
    }

    .message-actions {
      margin-top: 12px;
      padding-top: 12px;
      border-top: 1px solid #e4e7ed;
      display: flex;
      gap: 10px;
    }

    .loading-dots {
      span {
        animation: blink 1.4s infinite;
        &:nth-child(2) {
          animation-delay: 0.2s;
        }
        &:nth-child(3) {
          animation-delay: 0.4s;
        }
      }
    }
  }

  // 快捷命令区域
  .quick-commands {
    padding: 6px 12px;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    border-top: 1px solid #e4e7ed;

    .command-tag {
      cursor: pointer;
      transition: all 0.2s;
      font-size: 11px;
      user-select: none;

      i {
        margin-right: 3px;
        font-size: 11px;
      }

      &:hover {
        background-color: #1EB7E6 !important;
        color: white !important;
        border-color: #1EB7E6 !important;
      }
    }
  }

  // 输入区域
  .input-area {
    padding: 15px 20px;
    background-color: white;
    border-top: 1px solid #e4e7ed;

    .input-actions {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-top: 10px;

      .input-tip {
        font-size: 12px;
        color: #909399;
      }
    }
  }
}

@keyframes blink {
  0%, 100% {
    opacity: 0.2;
  }
  50% {
    opacity: 1;
  }
}

/* 选中文本提示区域 */
.selected-text-hint {
  background: linear-gradient(135deg, #f5f7fa 0%, #e8f4f8 100%);
  border: 1px solid #d0e8f2;
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 12px;
  box-shadow: 0 2px 8px rgba(30, 183, 230, 0.08);
  animation: slideDown 0.3s ease-out;

  .hint-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    font-size: 13px;
    color: #606266;

    i {
      font-size: 16px;
    }

    .hint-title {
      font-weight: 500;
      flex: 1;
    }

    .clear-btn {
      padding: 0;
      font-size: 16px;
      color: #909399;

      &:hover {
        color: #f56c6c;
      }
    }
  }

  .hint-content {
    background: white;
    padding: 8px 12px;
    border-radius: 4px;
    font-size: 13px;
    color: #303133;
    line-height: 1.6;
    word-break: break-all;
    border-left: 3px solid #1EB7E6;
  }
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>
